package com.hackordie.commons.hardware.computer;

import java.util.ArrayList;
import java.util.List;

import com.hackordie.commons.hardware.components.AComponent;
import com.hackordie.commons.hardware.components.Processor;
import com.hackordie.constants.EComponentsType;

public class Computer extends ComputerType implements IComputer {

    protected List<AComponent> components;    
    int availableEnergy;
    private int availableProcessorCapacity;

    public Computer(String name, int maxFirewalls, int maxProcessors, int maxNetworkCards,
            int maxHardDisks, int maxRams, int maxPowerSupplies, int price) {

        super(name, maxFirewalls, maxHardDisks, maxNetworkCards, maxPowerSupplies, 
              maxRams, maxProcessors, price);
               
        availableEnergy = 0;
        components = new ArrayList<AComponent>();
        availableProcessorCapacity = 0;
    }

    // getters and setters
    public List<AComponent> getComponentsList() {
        return components;
    }

    public AComponent getComponentByName(String name) {
        for (int i = 0; i < components.size(); i++) {
            if (components.get(i).getComponentName().equals(name)) {
                return components.get(i);
            }
        }
        return null;
    }

    public List<AComponent> getComponentByType(EComponentsType type) {

        List<AComponent> list = new ArrayList<AComponent>();

        for (int i = 0; i < components.size(); i++) {
            if (components.get(i).getComponentType().equals(type)) {
                list.add(components.get(i));
            }
        }

        return list;
    }

    public int getAvailableEnergy() {
        return availableEnergy;
    }
 
    public int getAvailableProcessorCapacity() {
        return availableProcessorCapacity;
    }

    public int getMaxComponentsType(EComponentsType componentsType) {        
        switch(componentsType) {
        case Firewall: 
            return getMaxFirewalls();
        case HardDisk:
            return getMaxFirewalls();
        case NetworkCard:
            return getMaxNetworkCards();
        case PowerSupply:
            return getMaxPowerSupplies();
        case Processor:
            return getMaxProcessors();
        case RamMemory:
            return getMaxRams();        
        }
        return -1;
    }
    // functions

    public boolean addComponent(AComponent component) {

        int actualComponents = getComponentByType(component.getComponentType()).size();

        if (actualComponents < getMaxComponentsType(component.getComponentType())) {
            components.add(component);          
            if (component.getComponentType() == EComponentsType.Processor) {
                calculateTotalProcessorCapacity();
            }
            return true;
        }
        return false;
    }

    public void removeComponentByName(String name) {

        int posicion = 0;
        boolean encontrado = false;

        do {
            if (components.get(posicion).getComponentName().equals(name)) {
                
                //hay que remover el componente antes de recalcular la capacidad
                if (components.get(posicion).getComponentType() == EComponentsType.Processor) {
                    components.remove(posicion);
                    calculateTotalProcessorCapacity();
                } else {
                    components.remove(posicion);
                }
                encontrado = true;
            }
            posicion++;
        } while (!encontrado && posicion < components.size());
    }

    public void removeComponentsByType(EComponentsType type) {

        for (int posicion = 0; posicion < components.size(); posicion++) {
            if (components.get(posicion).getComponentType().equals(type)) {
                components.remove(posicion);
            }
        }
        if(type == EComponentsType.Processor) {
            calculateTotalProcessorCapacity();
        }
    }

    public void removeAllComponents() {
        components.clear();
        calculateTotalProcessorCapacity();
    }
     
    private void calculateTotalProcessorCapacity() {
        availableProcessorCapacity = 0;
        for(int i = 0; i < components.size(); i++ ) {
            if(components.get(i).getComponentType() == EComponentsType.Processor) {
                availableProcessorCapacity += ((Processor)components.get(i)).getTotalCapacity();
            }                    
        }
    }
}
